﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections;

namespace ProgNetComponentsDx.Cache
{
    public class BaseCache<TKey, TValue>
    {
        private object synch = new object();

        private Dictionary<TKey, CacheItem<TValue>> _Items = new Dictionary<TKey, CacheItem<TValue>>();

        public TValue TryGetValue(TKey key, bool incrementUsage)
        {
            TValue result = default(TValue);
            lock (synch)
            {
                try
                {
                    if (_Items.ContainsKey(key))
                    {
                        var val = _Items[key];
                        result = val.Value;
                        if (incrementUsage)
                            val.IncrementUsage();
                    }
                }
                catch { }
            }
            return result;
        }

        public int CacheClearInterval
        {
            get;
            set;
        }
        private bool _IsClearTaskRunning;

        public void RunCleanTask()
        {
            bool run = false;
            lock (synch)
            {
                if (!_IsClearTaskRunning)
                {
                    _IsClearTaskRunning = true;
                    run = true;
                }
            }
            if (run)
            {
                Task task = Task.Factory.StartNew(ClearCache);
            }
        }
        private void ClearCache()
        {
            while (true)
            {
                for (int i = 0; i < CacheClearInterval; i++)
                {
                    System.Threading.Thread.Sleep(1000);
                }

                lock (synch)
                {

                }
            }
        }
    }

    public class CacheCleaner
    {
        public event EventHandler CacheItemCleared;

        public void ClearCache(IDictionary items)
        {
            ICacheItem item;
            List<object> delete = new List<object>();
            foreach (var key in items.Keys)
            {
                item = items[key] as ICacheItem;
                if (item != null)
                {
                    if (!item.IsUsed)
                        delete.Add(key);
                }
            }
            foreach (var key in delete)
                items.Remove(key);
            if (delete.Count > 0)
            {
                delete.Clear();
                GC.Collect();
            }
        }
    }

}
